import UIKit

// 主视图控制者
class ViewController: UIViewController, GameCallback {
    @IBOutlet private weak var mButtonMusic: UIButton!      // "音乐"按钮
    @IBOutlet private weak var mButtonPause: UIButton!      // "暂停"按钮
    private var mButtonPauseImage: UIImage!                 // "暂停"按钮图片
    private var mButtonPlayMusicImage: UIImage!             // "播放音乐"按钮图片
    private var mButtonResumeImage: UIImage!                // "继续"按钮图片
    private var mButtonStopMusicImage: UIImage!             // "停止音乐"按钮图片
    private var mGame: Game!                                // 游戏
    @IBOutlet private weak var mLabelDifficulty: UILabel!   // 难度值标签
    @IBOutlet private weak var mLabelScore: UILabel!        // 得分值标签

    /**
     * "加速下落"按钮的按下响应方法。
     */
    @IBAction private func onButtonDownDown() {
        mGame.downSpeedUp()
    }

    /**
     * "加速下落"按钮的抬起响应方法。
     */
    @IBAction private func onButtonDownUp() {
        mGame.cancelDownSpeedUp()
    }
    
    /**
     * "播放音乐"按钮的单击响应方法。
     */
    @IBAction private func onButtonMusicClicked() {
        let playingMusic = mGame.playMusic()
        if playingMusic {
            mButtonMusic.setImage(mButtonStopMusicImage, for: .normal)
        } else {
            mButtonMusic.setImage(mButtonPlayMusicImage, for: .normal)
        }
    }
        
    /**
     * "暂停"按钮的单击响应方法。
     */
    @IBAction private func onButtonPauseClicked() {
        mGame.pause()
        if mGame.status == .PAUSED {
            mButtonPause.setImage(mButtonResumeImage, for: .normal)
        } else if mGame.status == .PLAYING {
            mButtonPause.setImage(mButtonPauseImage, for: .normal)
        }
    }

    /**
     * "左移"、"右移"、"变形"按钮的单击响应方法。
     * @param sender    事件发送者，即用户单击的按钮
     */
    @IBAction private func onButtonPlayClicked(_ sender: UIButton) {
        switch sender.tag {
            case Const.TAG_BUTTON_LEFT:
                mGame.moveBlockLeft()
            case Const.TAG_BUTTON_RIGHT:
                mGame.moveBlockRight()
            case Const.TAG_BUTTON_TRANSFORM:
                mGame.transformBlock()
            default:
                break
        }
    }

    /**
     * "开始"按钮的单击响应方法。
     */
    @IBAction private func onButtonStartClicked() {
        // 游戏开始
        mGame.start()
         
        // 设置按钮状态
        mButtonPause.isEnabled = true
           
        // 设置按钮图片
        mButtonPause.setImage(mButtonPauseImage, for: .normal)
    
        // 设置状态栏文字
        self.onDifficultyUp(1)
        self.onScore(0)
    }

    /**
     * 难度增加事件的响应方法。
     * @param difficulty    难度
     */
    internal func onDifficultyUp(_ difficulty: Int) {
        mLabelDifficulty.text = String(difficulty)
    }

    /**
     * 游戏结束事件的响应方法。
     * @param isWon  胜利则为 true，否则为 false
     */
    internal func onGameOver(_ isWon: Bool) {
        if isWon {
            Toast.makeText(view, text: NSLocalizedString("IDS_WON", tableName: "Main", comment: ""), duration: Toast.LENGTH_LONG).show()
        } else {
            Toast.makeText(view, text: NSLocalizedString("IDS_LOST", tableName: "Main", comment: ""), duration: Toast.LENGTH_LONG).show()
        }
        mButtonPause.isEnabled = false
        mLabelDifficulty.text = NSLocalizedString("IDS_DIFFICULTY", tableName: "Main", comment: "")
        mLabelScore.text = NSLocalizedString("IDS_SCORE", tableName: "Main", comment: "")
    }

    /**
     * 视图不活动事件的响应方法。
     */
    @objc private func onResignActive() {
        if mGame.status == .PLAYING {
            self.onButtonPauseClicked()
        }
    }
    
    /**
     * 得分事件的响应方法。
     * @param score 得分
     */
    internal func onScore(_ score: Int) {
        mLabelScore.text = String(score)
    }

    /**
     * 视图加载事件的响应方法。
     */
    internal override func viewDidLoad() {
        super.viewDidLoad()
        
        // 初始化成员
        mButtonPauseImage = UIImage(named: Const.BUTTON_PAUSE_IMAGE_FILE_NAME)!
        mButtonPlayMusicImage = UIImage(named: Const.BUTTON_MUSIC_PLAY_IMAGE_FILE_NAME)!
        mButtonResumeImage = UIImage(named: Const.BUTTON_RESUME_IMAGE_FILE_NAME)!
        mButtonStopMusicImage = UIImage(named: Const.BUTTON_MUSIC_STOP_IMAGE_FILE_NAME)!

        // 将本页面设置为首页
        let window = UIApplication.shared.delegate?.window!
        window!.rootViewController = UINavigationController(rootViewController: self)
        
        // 设置导航栏的"返回"按钮的文字
        let back = NSLocalizedString("IDS_BACK", tableName: "Main", comment: "")
        navigationItem.backBarButtonItem = UIBarButtonItem(title: back, style: .plain, target: nil, action: nil)
        
        // 添加不活动事件监听者
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.onResignActive), name: UIApplication.willResignActiveNotification, object: nil)
        
        // 设置主视图背景
        view.layer.contents = UIImage(named: Const.IMAGE_FILE_NAME)!.cgImage!
        
        // 获取所有控件
        let buttonStart = view.viewWithTag(Const.TAG_BUTTON_START) as! UIButton
        let buttonLeft = view.viewWithTag(Const.TAG_BUTTON_LEFT)!
        let buttonRight = view.viewWithTag(Const.TAG_BUTTON_RIGHT)!
        let buttonTransform = view.viewWithTag(Const.TAG_BUTTON_TRANSFORM)!
        let buttonDown = view.viewWithTag(Const.TAG_BUTTON_DOWN)!

        // 禁用 translatesAutoresizingMaskIntoConstraints，否则控件约束将无效
        mLabelDifficulty.translatesAutoresizingMaskIntoConstraints = false
        mLabelScore.translatesAutoresizingMaskIntoConstraints = false
        buttonStart.translatesAutoresizingMaskIntoConstraints = false
        mButtonPause.translatesAutoresizingMaskIntoConstraints = false
        mButtonMusic.translatesAutoresizingMaskIntoConstraints = false
        buttonLeft.translatesAutoresizingMaskIntoConstraints = false
        buttonRight.translatesAutoresizingMaskIntoConstraints = false
        buttonTransform.translatesAutoresizingMaskIntoConstraints = false
        buttonDown.translatesAutoresizingMaskIntoConstraints = false

        // 获取可用的最大屏幕尺寸
        let screenY = (navigationController?.navigationBar.frame.height)! + UIApplication.shared.windows.first!.windowScene!.statusBarManager!.statusBarFrame.height
        let screenWidth = Int(UIScreen.main.bounds.width)
        let screenHeight = Int(UIScreen.main.bounds.height - screenY)

        // 计算格的尺寸
        Const.GRID_SIZE = screenWidth / (Const.GAME_BOARD_GRID_COUNT_H + Const.PREVIEW_GRID_COUNT_H + Const.PADDING_LEFT + Const.PADDING_MIDDLE + Const.PADDING_RIGHT)
        /* 如果纵向的所有格的尺寸加在一起大于屏幕高度，则以屏幕高度为基准、重新计算格的尺寸 */
        if Const.GRID_SIZE * Const.GAME_BOARD_GRID_COUNT_V > screenHeight {
            Const.GRID_SIZE = screenHeight / Const.GAME_BOARD_GRID_COUNT_V
        }

        // 创建游戏区域
        let gameBoardWidth = Const.GRID_SIZE * Const.GAME_BOARD_GRID_COUNT_H
        let gameBoardHeight = Const.GRID_SIZE * Const.GAME_BOARD_GRID_COUNT_V
        let gameBoardX = Const.GRID_SIZE * Const.PADDING_LEFT
        let gameBoardY = Int(screenY) + (screenHeight - gameBoardHeight) / 2
        let gameBoard = GameBoard(frame: CGRect(x: gameBoardX, y: gameBoardY, width: gameBoardWidth, height: gameBoardHeight))
        view.addSubview(gameBoard)

        // 创建预览区域
        let previewWidth = screenWidth - (Const.PADDING_LEFT + Const.PADDING_MIDDLE + Const.PADDING_RIGHT) * Const.GRID_SIZE - gameBoardWidth
        let previewHeight = Const.GRID_SIZE * Const.PREVIEW_GRID_COUNT_V
        let previewX = gameBoardX + gameBoardWidth + Const.GRID_SIZE
        let previewY = gameBoardY
        let preview = GameBoard(frame: CGRect(x: previewX, y: previewY, width: previewWidth, height: previewHeight))
        view.addSubview(preview)
        
        // 设置字体
        let textSize = CGFloat(Const.GRID_SIZE) * Const.SCALE_LABEL_TEXT_SIZE
        let font = UIFont.systemFont(ofSize: textSize)
        mLabelDifficulty.font = font
        mLabelScore.font = font
        
        // 计算控件尺寸
        let padding = CGFloat(Const.GRID_SIZE) * Const.SCALE_PADDING
        let imgBtnSize = (CGFloat(previewWidth) - padding) / 2
        let btnHeight = CGFloat(Const.GRID_SIZE) * Const.SCALE_BUTTON_HEIGHT

        // 设置按钮的尺寸和位置
        /* 所有功能按钮 */
        var buttons = [UIView]()
        buttons.append(mButtonMusic)
        buttons.append(mButtonPause)
        buttons.append(buttonStart)
        var prevBtn = buttonLeft
        for btn in buttons {
            let x = NSLayoutConstraint(item: btn, attribute: .left, relatedBy: .equal, toItem: preview, attribute: .left, multiplier: 1.0, constant: 0.0)
            let y = NSLayoutConstraint(item: btn, attribute: .bottom, relatedBy: .equal, toItem: prevBtn, attribute: .top, multiplier: 1.0, constant: -padding)
            let width = NSLayoutConstraint(item: btn, attribute: .width, relatedBy: .equal, toItem: preview, attribute: .width, multiplier: 1.0, constant: 0.0)
            let height = NSLayoutConstraint(item: btn, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: btnHeight)
            view.addConstraint(x)
            view.addConstraint(y)
            view.addConstraint(width)
            view.addConstraint(height)
            prevBtn = btn
        }
        
        /* "向左"按钮 */
        var x = NSLayoutConstraint(item: buttonLeft, attribute: .right, relatedBy: .equal, toItem: buttonRight, attribute: .left, multiplier: 1.0, constant: -padding)
        var y = NSLayoutConstraint(item: buttonLeft, attribute: .bottom, relatedBy: .equal, toItem: buttonTransform, attribute: .top, multiplier: 1.0, constant: -padding)
        var width = NSLayoutConstraint(item: buttonLeft, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: imgBtnSize)
        var height = NSLayoutConstraint(item: buttonLeft, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: imgBtnSize)
        view.addConstraint(x)
        view.addConstraint(y)
        buttonLeft.addConstraint(width)
        buttonLeft.addConstraint(height)

        /* "向右"按钮 */
        x = NSLayoutConstraint(item: buttonRight, attribute: .right, relatedBy: .equal, toItem: preview, attribute: .right, multiplier: 1.0, constant: 0.0)
        y = NSLayoutConstraint(item: buttonRight, attribute: .top, relatedBy: .equal, toItem: buttonLeft, attribute: .top, multiplier: 1.0, constant: 0.0)
        width = NSLayoutConstraint(item: buttonRight, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: imgBtnSize)
        height = NSLayoutConstraint(item: buttonRight, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: imgBtnSize)
        view.addConstraint(x)
        view.addConstraint(y)
        buttonRight.addConstraint(width)
        buttonRight.addConstraint(height)

        /* "变形"按钮 */
        x = NSLayoutConstraint(item: buttonTransform, attribute: .right, relatedBy: .equal, toItem: buttonDown, attribute: .left, multiplier: 1.0, constant: -padding)
        view.addConstraint(x)
        y = NSLayoutConstraint(item: buttonTransform, attribute: .bottom, relatedBy: .equal, toItem: gameBoard, attribute: .bottom, multiplier: 1.0, constant: 0.0)
        view.addConstraint(y)
        width = NSLayoutConstraint(item: buttonTransform, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: imgBtnSize)
        height = NSLayoutConstraint(item: buttonTransform, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: imgBtnSize)
        view.addConstraint(x)
        view.addConstraint(y)
        buttonTransform.addConstraint(width)
        buttonTransform.addConstraint(height)

        /* "加速下落"按钮 */
        x = NSLayoutConstraint(item: buttonDown, attribute: .right, relatedBy: .equal, toItem: preview, attribute: .right, multiplier: 1.0, constant: 0.0)
        y = NSLayoutConstraint(item: buttonDown, attribute: .top, relatedBy: .equal, toItem: buttonTransform, attribute: .top, multiplier: 1.0, constant: 0.0)
        width = NSLayoutConstraint(item: buttonDown, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: imgBtnSize)
        height = NSLayoutConstraint(item: buttonDown, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: imgBtnSize)
        view.addConstraint(x)
        view.addConstraint(y)
        buttonDown.addConstraint(width)
        buttonDown.addConstraint(height)
        
        // 设置状态栏
        var labels = [UIView]()
        labels.append(mLabelDifficulty)
        labels.append(mLabelScore)
        let lblWidth = CGFloat(screenWidth / labels.count)
        var i = CGFloat(0)
        for label in labels {
            let x = NSLayoutConstraint(item: label, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1.0, constant: lblWidth * i + padding)
            let y = NSLayoutConstraint(item: label, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1.0, constant: -padding)
            view.addConstraint(x)
            view.addConstraint(y)
            i += 1
        }
        
        // 创建游戏
        mGame = Game(self, gameBoard: gameBoard, gameBoardDrawer: gameBoard.drawer, preview: preview, previewDrawer: preview.drawer)
    }
}
